package com.mapsolute.map24webservices15.clients.axis.wrappers;


import com.mapsolute.map24webservices15.clients.axis.stubs.*;

/**
* As the name indicates, the Map24 ReverseGeocoder Service performs the opposite 
* operation of the Map24 Geocoder Service. From the input of a single coordinate 
* (for example a user's mouse click or a GPS signal) it searches surrounding map 
* objects and provides a textual description of the position. Determined by the 
* services configuration, among the results can also be distances and directions 
* to certain map object types. For example, a result could be "the position of the 
* given coordinate is 20 km northwest of Paris".
*
* This is a wrapper class with static methods for the different ways to 
* issue Map24 ReverseGeocoder Service requests. 
*/
public class Map24ReverseGeocoderWrapper 
{
	
	/** 
	 * Helper method for instantiating a LayerSpecifier for a reverseGeocode request.
	 * 
	 * @param name 		The layer name in which the ReverseGeocoder should look for map objects. 
	 *                The layer names can be retrieved with a getMapConfiguration operation.
	 * @return				An instance of LayerSpecifier.
	 */
	public static LayerSpecifier LayerSpecifier(String name)
	{
		LayerSpecifier ls= new LayerSpecifier();
		
		ls.setAlternativeLayers(new String[] { name });
		ls.setName(name);
		
		return ls;
	}
	
	
	/** 
	 * Helper method for instantiating a LayerSpecifier for a reverseGeocode request.
	 * 
	 * @param name 		The layer name in which the ReverseGeocoder should look for map objects. 
	 *								The layer names can be retrieved with a getMapConfiguration operation. 
	 *								Alternatively, if you want to look for map objects in multiple layers, 
	 *								it is possible to specify a name such as "AnyCities". Then you have to 
	 *								specify the layers to search in in the AlternativeLayers field.
	 * @param alternativeLayers An array that holds the names of layers that will alternatively 
	 *								be taken into account. For example, if a map provides the layers "Metropolis", 
	 *								"LargeCities" and "Cities", a reverseGeocodePoints request which receives a 
	 *								LayerSpecifier with Name "AnyCities" and the AlternativeLayers "Metropolis", 
	 *								"LargeCities", and "Cities" will return a reverse geocoded layer with map 
	 *								objects from all 3 layers and name "AnyCities".
	 * @return				An instance of LayerSpecifier.
	 */
	public static LayerSpecifier LayerSpecifier(String name, String[] alternativeLayers)
	{
		LayerSpecifier ls= new LayerSpecifier();
		
		ls.setAlternativeLayers(alternativeLayers);
		ls.setName(name);
		
		return ls;
	}
	
	
	//LayerSpecifier("PostalCodeAreas",  new String[] { "PostalCodeLines"}, (Float) 1000f, (Integer) 1, (Boolean) true),
	
   /** 
	 * Helper method for instantiating a LayerSpecifier for a reverseGeocode request.
	 * 
	 * @param name 		The layer name in which the ReverseGeocoder should look for map objects. 
	 *								The layer names can be retrieved with a getMapConfiguration operation. 
	 *								Alternatively, if you want to look for map objects in multiple layers, 
	 *								it is possible to specify a name such as "AnyCities". Then you have to 
	 *								specify the layers to search in in the AlternativeLayers field.
	 * @param alternativeLayers An array that holds the names of layers that will alternatively 
	 *								be taken into account. For example, if a map provides the layers "Metropolis", 
	 *								"LargeCities" and "Cities", a reverseGeocodePoints request which receives a 
	 *								LayerSpecifier with Name "AnyCities" and the AlternativeLayers "Metropolis", 
	 *								"LargeCities", and "Cities" will return a reverse geocoded layer with map 
	 *								objects from all 3 layers and name "AnyCities".
	 * @param radius	The search radius (in meters). A radius of 0 indicates that the search should 
	 *								continue until at least one object is found.
	 * @param maxNoOfObjects The maximum number of map objects to be searched in a layer.
	 * @param getShape Flag that indicates whether the shape of the found objects shall be included in the response 
	 *								 (the shape will be returned for polylines and polygons; all other map objects are of type POINT).
	 * @return				An instance of LayerSpecifier.
	 */
	public static LayerSpecifier LayerSpecifier(String name, String[] alternativeLayers, Float radius, Integer maxNoOfObjects, Boolean getShape)
	{
		LayerSpecifier ls= new LayerSpecifier();
		
		ls.setAlternativeLayers(alternativeLayers);
		ls.setName(name);
		ls.setRadius(radius);
		ls.setMaxNoOfMapObjects(maxNoOfObjects);
		ls.setGetShape(getShape);
		
		return ls;
	}
	
	private static Map24ReverseGeocoderPortType GetMap24ReverseGeocoderPort(String binding, String map24id, String clientid) throws Exception
	{ 	
		Map24ReverseGeocoderLocator locator= new Map24ReverseGeocoderLocator();
				
		// DEBUG: try to create a port with other URL (e.g. proxy connection)
		if (binding == null)
			return locator.getMap24ReverseGeocoderPort();
		
		java.net.URL url = new java.net.URL(binding+"&sid="+clientid);
			
		return locator.getMap24ReverseGeocoderPort(url);
			
	 } // GetMap24ReverseGeocoderPort
	
	
	/** 
	 * Helper method for searching for a map object in all given layers.
	 *
	 * The reverseGeocodePoints operation searches for map objects in specified map layers. 
	 * The map layers are defined in the LayerSpecifier element.
	 * The given radius is applied to all LayerSpecifiers.
	 * MaxNoOfMapObjects is set to 1 for each layer.
	 * 
	 * 
	 * @param binding 			The service that is used, for example ""http://maptp12.map24.com/map24/webservices1.5?soap=Map24ReverseGeocoder". 
	 *                      If null, the server URL specified in the client stub Map24Geocoder51Locator is used.
	 * @param map24id 	    The Map24 ID used for authentication.
	 * @param clientid 		  ID of the client that has initiated a request (SessionID).
	 * @param layerspecs 		An array of LayerSpecifier objects used for specifying the layers to search in.
	 * @param coords 				An array of Coordinate objects for specifing the coordinates around which the search is performed.
	 * @param radius 				The search radius (in meters). A radius of 0 indicates that the search should 
	 *											continue until at least one object is found.
	 * @return							The response containing a map object for each given layer (if existing).
	 */
   public static ReverseGeocodePointsResponse ReverseGeocodePoints(String binding, String map24id, String clientid, LayerSpecifier[] layerspecs, Coordinate[] coords, int radius)
   {
   		/////////////////////////////////////////////////////		
		// create ReverseGeocodePointsRequest
		/////////////////////////////////////////////////////
   		for (int i= 0; ((layerspecs != null) && (i < layerspecs.length)); i++)
   		{
   			layerspecs[i].setRadius((float)radius);
   			layerspecs[i].setMaxNoOfMapObjects(1);
   		}	
   		
   		ReverseGeocodePointsRequest request = new ReverseGeocodePointsRequest();
   		request.setCoordinates(coords);
   		request.setLayerSpecifiers(layerspecs);
   		
   	
		/////////////////////////////////////////////////////		
		// create RequestHeader
		/////////////////////////////////////////////////////
		RequestHeader requestHeader = new RequestHeader();
		requestHeader.setMap24ID  (map24id);
		requestHeader.setClientID (clientid);
							
		try 
		{	return GetMap24ReverseGeocoderPort(binding, map24id, clientid).reverseGeocodePoints(requestHeader, request);		
		}
		catch(Exception e)
		{
			System.err.println(e);
		}
		
		return null;
		
   } // ReverseGeocodePoints
   
   
	/** 
	 * Helper method for sending a getMapConfiguration request.
	 * 
	 * A getMapConfiguration request returns the names of all available map layers. You can use this information
	 * for performing a reverseGeocodePoints request.
	 *
	 * @param binding 			The service that is used, for example ""http://maptp12.map24.com/map24/webservices1.5?soap=Map24ReverseGeocoder". 
	 *                      If null, the server URL specified in the client stub Map24Geocoder51Locator is used.
	 * @param map24id 	    The Map24 ID used for authentication.
	 * @param clientid 		  ID of the client that has initiated a request (SessionID).
	 * @return							The response containing the names of all available map layers.
	 */
  public static MapConfigurationResponse GetMapConfiguration(String binding, String map24id, String clientid)
  {
		/////////////////////////////////////////////////////		
		// create RequestHeader
		/////////////////////////////////////////////////////
		RequestHeader requestHeader = new RequestHeader();
		requestHeader.setMap24ID  (map24id);
		requestHeader.setClientID (clientid);
							
		try 
		{	return GetMap24ReverseGeocoderPort(binding, map24id, clientid).getMapConfiguration(requestHeader);		
		}
		catch(Exception e)
		{
			System.err.println(e);
		}
		
		return null;
		
  } // GetMapConfiguration
	
   
} // Map24ReverseGeocoderWrapper
